pass
## 08 错误和异常

### 8.1. 语法错误

#while True print('Hello')       # SyntaxError: invalid syntax

### 8.2. 异常

#10*(1/0)        # ZeroDivisionError: division by zero

### 8.3. 处理异常

'''try .. except

except (RuntimeError, TypeError, NameError): 可同时处理多个  
'''

'''else 语句
except 未捕获时处理
try ... except ... else ...
'''

while True:
    try:
        x = int(input("Please enter a number: "))
        break
    except ValueError:
        print("No valid number , Try again..")

### 8.4. 抛出异常

'''raise 语句
eg: 
raise NameError('HiThere')
'''

### 8.5. 用户自定义异常
'''直接或间接从 Exception 类派生
基类:
    通常会创建一个基类
命名: 
    大多数异常都定义为名称以“Error”结尾，类似于标准异常的命名。
'''

class Error(Exception):
    """Base class for exceptions i this module"""
    pass

class InputError(Error):
    """Exception raised for errors in the input.
    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

try:
    a = 'a'
    raise InputError(f'a = {a}', '输入异常')
except InputError as ir:
    print("except InputError: ", ir.expression, ir.message)

### 8.6. 定义清理操作
'''finally 子句   
所有情况下执行
'''

try:
    a2 = 'a2'
    raise InputError(f'a2 = {a}', '输入异常')
except InputError as ir:
    print("except InputError: ", ir.expression, ir.message)
finally:
    print("this is finally statement.")

'''
如果在执行 try 子句期间发生了异常，该异常可由一个 except 子句进行处理。 
如果异常没有被某个 except 子句所处理，则该异常会在 finally 子句执行之后被重新引发。

异常也可能在 except 或 else 子句执行期间发生。 
同样地，该异常会在 finally 子句执行之后被重新引发。

如果在执行 try 语句时遇到一个 break, continue 或 return 语句，
则 finally 子句将在执行 break, continue 或 return 语句之前被执行。

如果 finally 子句中包含一个 return 语句，则返回值将来自 finally 子句的某个 return 语句的返回值，
而非来自 try 子句的 return 语句的返回值。
'''
def bool_return():          # False
    try:
        return True
    finally:
        return False


### 8.7. 预定义的清理操作

'''某些对象定义了在不再需要该对象时要执行的标准清理操作
'''

for line in open("myfile.txt"):
    print(line, end="")
'''
这个代码的问题在于，
它在这部分代码执行完后，
会使文件在一段不确定的时间内处于打开状态
'''

with open("myfile.txt") as f:
    for line in f:
        print(line, end='')
'''改进后的代码
执行完语句后，即使在处理行时遇到问题，文件 f 也始终会被关闭
'''